package pl.edu.pw.MidEmu.Logic;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import pl.edu.pw.MidEmu.Common.Consts;
import pl.edu.pw.MidEmu.Common.Models.ClassSettingsModel;

/**
 * Service class responsible for launching and terminating MIDAS enabled applications 
 * @author Mateusz Starodab
 *
 */
public class ApplicationService
{
	private List<ClassSettingsModel> classSettingsHistory = null;

	/**
	 * Default constructor
	 */
	public ApplicationService()
	{
		if (classSettingsHistory == null)
		{
			load();
		}
	}

	/**
	 * Adds application
	 * @param model Model representing application to add
	 */
	public void addModel(ClassSettingsModel model)
	{
		if (classSettingsHistory.contains(model))
		{
			classSettingsHistory.remove(model);
			classSettingsHistory.add(model);
		}
		else if (classSettingsHistory.size() <= Consts.ClassLoder_MaxHistorySize)
		{
			classSettingsHistory.add(0, model);
		}
		if (classSettingsHistory.size() > Consts.ClassLoder_MaxHistorySize)
		{
			classSettingsHistory.remove(classSettingsHistory.size() - 1);
		}

		try
		{
			XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(Consts.FilePath_ClassSettingsHistory)));
			encoder.writeObject(classSettingsHistory);
			encoder.close();
		}
		catch (FileNotFoundException ex)
		{
			ex.printStackTrace();
		}
	}
	
	/**
	 * Gets history of loaded applications
	 * @return List with history models
	 */
	public List<ClassSettingsModel> getClassSettingsHistory(boolean b)
	{
		if (b)
			load();
		return classSettingsHistory;
	}

	/**
	 * Loads class setting model form file
	 * @param path Path to file containing serialized class setting model
	 * @return class setting model
	 */
	public ClassSettingsModel getModel(String path)
	{
		Iterator<ClassSettingsModel> iterator = classSettingsHistory.iterator();

		while (iterator.hasNext())
		{
			ClassSettingsModel model = iterator.next();
			if (model.get_path().equals(path))
				return model;
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	/**
	 * Loads application history
	 */
	private void load()
	{
		classSettingsHistory = new ArrayList<ClassSettingsModel>();
		try
		{
			File file = new File(Consts.FilePath_ClassSettingsHistory);
			if (file.exists())
			{
				XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(file)));
				classSettingsHistory = (List<ClassSettingsModel>) decoder.readObject();
				decoder.close();
			}
		}
		catch (FileNotFoundException ex)
		{
			ex.printStackTrace();
		}
	}

	/**
	 * Removes application from list
	 * @param selectedModel Model to remove
	 */
	public void removeModel(ClassSettingsModel selectedModel)
	{
		if (classSettingsHistory.contains(selectedModel))
		{
			classSettingsHistory.remove(selectedModel);
			try
			{
				XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(Consts.FilePath_ClassSettingsHistory)));
				encoder.writeObject(classSettingsHistory);
				encoder.close();
			}
			catch (FileNotFoundException ex)
			{
				ex.printStackTrace();
			}
		}
	}
}
